/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Module Name          : com.yaodian100.ec.coupon.web.CouponMaintainAction
Module Description   :

Date Created      : 2009/12/14
Original Author   : jeff.ma
Team              : yaodian100
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MODIFICATION HISTORY
------------------------------------------------------------------------------
Date Modified       Modified by       Comments
------------------------------------------------------------------------------
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
package com.yaodian100.ec.coupon.web;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;

import com.csvreader.CsvWriter;
import com.yaodian100.core.common.utils.DateUtil;
import com.yaodian100.core.menu.entity.Menu;
import com.yaodian100.core.menu.service.MenuService;
import com.yaodian100.ec.category.entity.Category;
import com.yaodian100.ec.category.service.CategoryService;
import com.yaodian100.ec.common.EcConstant;
import com.yaodian100.ec.common.web.AbstractAction;
import com.yaodian100.ec.coupon.entity.Coupon;
import com.yaodian100.ec.coupon.entity.CouponItem;
import com.yaodian100.ec.coupon.entity.Coupon.ApplyRangType;
import com.yaodian100.ec.coupon.entity.Coupon.Status;
import com.yaodian100.ec.coupon.service.CouponService;
import com.yaodian100.ec.product.entity.Product;
import com.yaodian100.ec.product.service.ProductService;

/**
 * @author jeff.ma
 * 
 */
public class CouponMaintainAction extends AbstractAction {

	private static final String FIELD_NAME_APPLY_RANGE_TYPE_EXTENSION = "applyRangeTypeExtension";
	private static final String CATEGORY_PATH_SEPARATOR = "/";
	private static final String APPLY_RANGE_TYPE_EXTENSION_SEPARATOR = ",";
	private static final String FIELD_NAME_MINIMUM_PRODUCT_PRICE = "minimumProductPrice";
	private static final String RESULT_VIEW_COUPON_ITEM = "viewCouponItem";
	private static final String RESULT_QUERY_COUPON_BY_COUPON_ITEM_CODE = "queryCouponByCouponItemCode";
	private static final String RESULT_EXPORT_COUPON_ITEM_CODE_LIST = "exportCouponItemCodeList";

	private static final String RESULT_EDIT_COUPON_ITEM = "editCouponItem";

	private static final String FROM_COUPON = "fc";

	/** serialVersionUID */
	private static final long serialVersionUID = 3442840197718883894L;
	@Autowired
	private CouponService couponService;
	@Autowired
	private MenuService menuService;
	@Autowired
	private CategoryService categoryService;
	@Autowired
	private ProductService productService;

	private String couponUuid;
	private InputStream inputStream;

	/* coupon attribute */
	private String name;
	private String description;
	private String startDate;
	private String endDate;
	private long amount;
	private String applyRangeTypeExtension;
	private BigDecimal faceValue;

	// 頁面顯示用的 value object
	private Coupon coupon;
	private CouponItem couponItem;
	private String couponItemCode;
	private List<CouponItem> couponItems;

	private String applyRangeTypeStr;
	private String statusStr;
	private BigDecimal minimumProductPrice;

	private File uploadFile;
	private String sendMail;
	private Boolean isOnce;
	private String activityLink;
	private String startTime;
	private String endTime;
	private String budget;

	private Date sd;
	private Date ed;

	/* prepare menu */
	private Menu statusMenu;
	private Menu applyRangTypeMenu;
	private Menu menuBudget;

	private boolean creatingCoupon;

	private String from;
	private String jsonResult;

	/** default constructor */
	public CouponMaintainAction() {
	}

	/**
	 * @return the inputStream
	 */
	public InputStream getInputStream() {
		return inputStream;
	}

	private void toCouponAndValidate(Coupon coupon) throws ParseException {
		DateFormat format = new SimpleDateFormat(EcConstant.PATTERN_DATE);
		coupon.setName(name);
		coupon.setDescription(description);
		coupon.setAmount(amount);
		coupon.setFaceValue(faceValue);
		coupon.setApplyRangeType(Coupon.ApplyRangType.valueOf(applyRangeTypeStr));
		coupon.setBudget(budget);
		String applyRangeTypeExtensionForDb = convertApplyRangeTypeExtensionForDbAndValidate();
		coupon.setApplyRangeTypeExtension(applyRangeTypeExtensionForDb);
		coupon.setMinimumProductPrice(this.minimumProductPrice);
		if (statusStr.equals(Status.INIT.name()) && null != startDate && null != endDate) {
			coupon
					.setStartDate(DateUtil.convertStringToDate(EcConstant.PATTERN_TIMESTAMP_HH_MM, startDate + " " + startTime));
			coupon.setEndDate(DateUtil.convertStringToDate(EcConstant.PATTERN_TIMESTAMP_HH_MM, endDate + " " + endTime));
		}
		if (this.isOnce == null) {
			coupon.setIsOnce(Boolean.valueOf(false));
		} else {
			coupon.setIsOnce(this.isOnce);
		}

		coupon.setActivityLink(this.activityLink);
	}

	private String convertApplyRangeTypeExtensionForDbAndValidate() {
		if (Coupon.ApplyRangType.ALL.name().equals(getApplyRangeTypeStr())) {
			if (StringUtils.trimToNull(applyRangeTypeExtension) != null) {
				addFieldError(FIELD_NAME_APPLY_RANGE_TYPE_EXTENSION, "适用范围是全馆时，不应输入范围设定");
			}
			return null;
		}

		String applyRangeTypeExtensionForDb;
		if (this.applyRangeTypeExtension != null) {
			List<String> applyRangeTypeExtensionList = new ArrayList<String>();
			String trimmedApplyRangeTypeExtension = StringUtils.trimToEmpty(this.applyRangeTypeExtension);
			String applyRangeTypeExtensionNoSpace = StringUtils.remove(trimmedApplyRangeTypeExtension, ' ');
			String[] applyRangeTypeExtensionArray = StringUtils.split(applyRangeTypeExtensionNoSpace,
					APPLY_RANGE_TYPE_EXTENSION_SEPARATOR);
			for (String oneApplyRangeTypeExtension : applyRangeTypeExtensionArray) {
				if (this.applyRangeTypeStr.equals(Coupon.ApplyRangType.CATEGORY.getCode())) {
					String categoryIdString = oneApplyRangeTypeExtension;
					if (!StringUtils.isNumeric(categoryIdString)) {
						addFieldError(FIELD_NAME_APPLY_RANGE_TYPE_EXTENSION, categoryIdString + "：类别代码错误");
						continue;
					}
					Long categoryId = Long.valueOf(categoryIdString);
					Category category = this.categoryService.get(categoryId);
					if (category == null) {
						addFieldError(FIELD_NAME_APPLY_RANGE_TYPE_EXTENSION, categoryId + "：无此类别");
						continue;
					}
					if (StringUtils.isBlank(category.getCategoryPath())) {
						addFieldError(FIELD_NAME_APPLY_RANGE_TYPE_EXTENSION, categoryId + "：category path 未设定");
						continue;
					}
					applyRangeTypeExtensionList.add(category.getCategoryPath());
				} else {
					String productId = oneApplyRangeTypeExtension;
					Product product = this.productService.get(productId);
					if (product == null) {
						addFieldError(FIELD_NAME_APPLY_RANGE_TYPE_EXTENSION, productId + "：无此产品");
						continue;
					}
					applyRangeTypeExtensionList.add(productId);
				}
			}
			applyRangeTypeExtensionForDb = StringUtils.join(applyRangeTypeExtensionList.toArray(),
					APPLY_RANGE_TYPE_EXTENSION_SEPARATOR);

			// List<String> applyRangeTypeExtensionFieldError = getFieldErrors().get(FIELD_NAME_APPLY_RANGE_TYPE_EXTENSION);
			// if (applyRangeTypeExtensionFieldError == null || applyRangeTypeExtensionFieldError.isEmpty()) {
			// coupon.setApplyRangeTypeExtension(applyRangeTypeExtensionForDb);
			// }
		} else {
			applyRangeTypeExtensionForDb = null;
		}
		return applyRangeTypeExtensionForDb;
	}

	private void fromCoupon(Coupon coupon) {
		name = coupon.getName();
		description = coupon.getDescription();
		amount = coupon.getAmount();
		faceValue = coupon.getFaceValue();
		statusStr = coupon.getStatus().name();
		budget = coupon.getBudget();
		startDate = DateUtil.convertDateToString(EcConstant.PATTERN_TIMESTAMP_HH_MM, coupon.getStartDate());
		endDate = DateUtil.convertDateToString(EcConstant.PATTERN_TIMESTAMP_HH_MM, coupon.getEndDate());
		applyRangeTypeStr = coupon.getApplyRangeType().name();
		applyRangeTypeExtension = coupon.getApplyRangeTypeExtension();
		if (coupon.getIsOnce() == null) {
			this.isOnce = Boolean.valueOf(false);
		} else {
			this.isOnce = coupon.getIsOnce();
		}
		this.minimumProductPrice = coupon.getMinimumProductPrice();
		this.activityLink = coupon.getActivityLink();
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @return the description
	 */
	public String getDescription() {
		return description;
	}

	/**
	 * @param description the description to set
	 */
	public void setDescription(String description) {
		this.description = description;
	}

	/**
	 * @return the applyRangeTypeExtension
	 */
	public String getApplyRangeTypeExtension() {
		return applyRangeTypeExtension;
	}

	/**
	 * @param applyRangeTypeExtension the applyRangeTypeExtension to set
	 */
	public void setApplyRangeTypeExtension(String applyRangeTypeExtension) {
		if (applyRangeTypeExtension != null) {
			applyRangeTypeExtension = StringUtils.remove(applyRangeTypeExtension, "\r\n");
			applyRangeTypeExtension = StringUtils.remove(applyRangeTypeExtension, "\n");
			applyRangeTypeExtension = StringUtils.remove(applyRangeTypeExtension, "\r");
			applyRangeTypeExtension = StringUtils.remove(applyRangeTypeExtension, System.getProperty("line.separator"));
			applyRangeTypeExtension = StringUtils.remove(applyRangeTypeExtension, " ");
		}
		this.applyRangeTypeExtension = StringUtils.remove(applyRangeTypeExtension, ' ');
	}

	public String getStartDate() {
		return startDate;
	}

	public void setStartDate(String startDate) {
		this.startDate = startDate;
	}

	public String getEndDate() {
		return endDate;
	}

	public void setEndDate(String endDate) {
		this.endDate = endDate;
	}

	/**
	 * @return the amount
	 */
	public long getAmount() {
		return amount;
	}

	/**
	 * @param amount the amount to set
	 */
	public void setAmount(long amount) {
		this.amount = amount;
	}

	/**
	 * @return the faceValue
	 */
	public String getFaceValue() {
		if (faceValue != null) {
			return faceValue.toString();
		} else {
			return "";
		}
	}

	/**
	 * @param faceValue the faceValue to set
	 */
	public void setFaceValue(String faceValue) {
		if (StringUtils.isNotBlank(faceValue)) {
			this.faceValue = new BigDecimal(faceValue);
		}
	}

	/**
	 * @return the applyRangeTypeStr
	 */
	public String getApplyRangeTypeStr() {
		return applyRangeTypeStr;
	}

	/**
	 * @param applyRangeTypeStr the applyRangeTypeStr to set
	 */
	public void setApplyRangeTypeStr(String applyRangeTypeStr) {
		this.applyRangeTypeStr = applyRangeTypeStr;
	}

	/**
	 * @return the statusStr
	 */
	public String getStatusStr() {
		return statusStr;
	}

	/**
	 * @param statusStr the statusStr to set
	 */
	public void setStatusStr(String statusStr) {
		this.statusStr = statusStr;
	}

	/**
	 * @return the statusMenu
	 */
	public Menu getStatusMenu() {
		return statusMenu;
	}

	/**
	 * @param statusMenu the statusMenu to set
	 */
	public void setStatusMenu(Menu statusMenu) {
		this.statusMenu = statusMenu;
	}

	/**
	 * @return the applyRangTypeMenu
	 */
	public Menu getApplyRangTypeMenu() {
		return applyRangTypeMenu;
	}

	/**
	 * @param applyRangTypeMenu the applyRangTypeMenu to set
	 */
	public void setApplyRangTypeMenu(Menu applyRangTypeMenu) {
		this.applyRangTypeMenu = applyRangTypeMenu;
	}

	/**
	 * @return the couponUuid
	 */
	public String getCouponUuid() {
		return couponUuid;
	}

	/**
	 * @param couponUuid the couponUuid to set
	 */
	public void setCouponUuid(String couponUuid) {
		this.couponUuid = couponUuid;
	}

	/**
	 * @return the uploadFile
	 */
	public File getUploadFile() {
		return uploadFile;
	}

	/**
	 * @param uploadFile the uploadFile to set
	 */
	public void setUploadFile(File uploadFile) {
		this.uploadFile = uploadFile;
	}

	public void setUploadFile(String uploadFile) {
		this.uploadFile = new File(uploadFile);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.opensymphony.xwork2.Preparable#prepare()
	 */
	@Override
	public void prepare() throws Exception {
		super.prepare();
		clearActionErrors();
		if (statusMenu == null) {
			statusMenu = menuService.get("Coupon.status");
		}
		if (applyRangTypeMenu == null) {
			applyRangTypeMenu = menuService.get("Coupon.applyRangType");
		}
		if (menuBudget == null) {
			menuBudget = menuService.get("Budget");
		}
	}

	public String view() {
		try {
			Coupon coupon = couponService.get(couponUuid);
			if (coupon == null) {
				addActionError("Coupon 不存在");
				return "list";
			}
			fromCoupon(coupon);
			setCoupon(coupon);
		} catch (Exception e) {
			addActionError(e.getLocalizedMessage());
			return "list";
		}
		return "view";
	}

	public String listCouponItem() {
		getPager().setPageRecord(10);
		getPager().setTotalSize(couponService.getAllItemsSize(couponUuid));
		couponItems = couponService.getListItems(couponUuid, getPager().getCurrentPage() * getPager().getPageRecord(),
				getPager().getPageRecord());
		return "listCouponItem";
	}

	public String list() {
		return "list";
	}

	public String edit() {
		Coupon targetCouupon = this.couponService.get(couponUuid);
		setCoupon(targetCouupon);
		setCreatingCoupon(false);
		/*
		if (statusStr.equals(Status.INIT.name()) && startDate.length() > 0 && endDate.length() > 0) {
			setCreatingCoupon(true);
			setStartTime(startDate.substring(11, 16));
			setEndTime(endDate.substring(11, 16));
			setStartDate(startDate.substring(0, 10));
			setEndDate(endDate.substring(0, 10));
		} else {
			setStartTime("00:00");
			setEndTime("23:59");
		}
		*/
		return "edit";
	}

	public String create() {
		// 预设值
		startDate = DateUtil.convertDateToString(EcConstant.PATTERN_DATE, DateUtil.getTodayAddDays(7).getTime());
		endDate = DateUtil.convertDateToString(EcConstant.PATTERN_DATE, DateUtil.getTodayAddDays(50).getTime());
		statusStr = Status.INIT.name();
		applyRangeTypeStr = ApplyRangType.ALL.name();
		this.isOnce = Boolean.valueOf(false);
		setCreatingCoupon(true);
		setStartTime("00:00");
		setEndTime("23:59");
		setBudget("A");
		return "edit";
	}

	public String generate() {
		try {
			Coupon coupon = null;
			if (StringUtils.isNotEmpty(couponUuid)) {
				coupon = couponService.get(couponUuid);
				if (coupon == null || Coupon.Status.USED.equals(coupon.getStatus())) {
					addActionError("Coupon 状态不正确, 已使用不可重建");
					return view();
				}
			} else {
				coupon = new Coupon();
			}
			validateFields();
			toCouponAndValidate(coupon);
			try {
				setStartEndDate(coupon);
			} catch (ParseException pe) {
				addActionError("日期时间格式不正确");
			}

			if (hasErrors()) {
				return "edit";
			}

			coupon = couponService.generate(coupon, uploadFile, sendMail, sd, ed);
			couponUuid = coupon.getUuid();
			setCoupon(coupon);
		} catch (Exception e) {
			e.printStackTrace();
			addActionError(e.getLocalizedMessage());
			return "edit";
		}
		fromCoupon(coupon);
		return "view";
	}

	public String save() {
		try {
			Coupon coupon = null;
			if (StringUtils.isNotBlank(couponUuid)) {
				coupon = couponService.get(couponUuid);
				if (coupon == null) {
					addActionError("Coupon 不存在");
					return "list";
				}
			} else {
				coupon = new Coupon();
			}

			validateFields();
			toCouponAndValidate(coupon);

			try {
				setStartEndDate(coupon);
			} catch (ParseException pe) {
				addActionError("日期时间格式不正确");
			}

			if (hasErrors()) {
				return "edit";
			}

			coupon = couponService.save(coupon);
			couponUuid = coupon.getUuid();
			if (statusStr.equals(Status.INIT.name()) && null != sd && null != ed) {
				couponService.updateStartEndDate(couponUuid, sd, ed);
			}

			setCoupon(coupon);
		} catch (Exception e) {
			e.printStackTrace();
			addActionError(e.getLocalizedMessage());
		}
		fromCoupon(coupon);
		return "view";
	}

	private void validateFields() {
		if (getMinimumProductPrice() == null) {
			addFieldError(FIELD_NAME_MINIMUM_PRODUCT_PRICE, "最低商品价格不能为空值");
		}
		if (getMinimumProductPrice().doubleValue() <= 0) {
			addFieldError(FIELD_NAME_MINIMUM_PRODUCT_PRICE, "最低商品价格必须是正浮点数");
		}
		if (getMinimumProductPrice().doubleValue() < this.faceValue.doubleValue()) {
			addFieldError(FIELD_NAME_MINIMUM_PRODUCT_PRICE, "最低商品价格必须大於面额");
		}
		if (StringUtils.isBlank(budget)) {
			addFieldError("", "请选取预算归属");
		}
	}

	public String delete() {
		try {
			if (StringUtils.isNotBlank(couponUuid)) {
				Coupon coupon = couponService.get(couponUuid);
				if (coupon != null) {
					if (Coupon.Status.USED.equals(coupon.getStatus())) {
						addActionError("Coupon 已经被使用, 无法删除, 仅可设定说明,使用期限");
					} else {
						couponService.delete(coupon);
					}
				} else {
					addActionError("Coupon 不存在, uuid:" + couponUuid);
				}
			} else {
				addActionError("Coupon 不存在, uuid is null");
			}
		} catch (Exception e) {
			addActionError(e.getLocalizedMessage());
		}
		return "list";
	}

	public String export() {
		ByteArrayOutputStream output = new ByteArrayOutputStream();
		try {
			CsvWriter w = new CsvWriter(output, ',', Charset.forName("UTF-8"));
			w.writeRecord(new String[] { "UUID" });
			List<CouponItem> items = couponService.getAllItems(couponUuid);
			for (CouponItem item : items) {
				w.writeRecord(new String[] { item.getUuid() });
			}
			w.flush();
			w.close();
			inputStream = new ByteArrayInputStream(output.toByteArray());
			output.flush();
			output.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "export";
	}

	public String exportCouponItemCodeList() {
		ByteArrayOutputStream output = new ByteArrayOutputStream();
		try {
			CsvWriter w = new CsvWriter(output, ',', Charset.forName("UTF-8"));
			List<CouponItem> items = couponService.getAllItems(couponUuid);
			for (CouponItem item : items) {
				if (item == null) {
					continue;
				}
				if (item.getMemberId() != null) {
					continue;
				}
				w.writeRecord(new String[] { item.getCode() });
			}
			w.flush();
			w.close();
			inputStream = new ByteArrayInputStream(output.toByteArray());
			output.flush();
			output.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return RESULT_EXPORT_COUPON_ITEM_CODE_LIST;
	}

	public String toQueryCouponByCouponItemCode() {
		return RESULT_QUERY_COUPON_BY_COUPON_ITEM_CODE;
	}

	public String queryCouponByCouponItemCode() {
		String couponItemCode = getCouponItemCode();
		CouponItem couponItem = couponService.getCouponItemByCode(couponItemCode);
		if (couponItem != null) {
			this.couponUuid = couponItem.getCoupon().getUuid();
			setCoupon(couponItem.getCoupon());
			setCouponItem(couponItem);
			return RESULT_VIEW_COUPON_ITEM;
		}
		addActionMessage("优惠码（Coupon Item Code）查无资料");
		return RESULT_QUERY_COUPON_BY_COUPON_ITEM_CODE;
	}

	/**
	 * 编辑couponItem
	 * 
	 * @return
	 */
	public String editCouponByCouponItemCode() {
		String couponItemCode = getCouponItemCode();
		CouponItem couponItem = couponService.getCouponItemByCode(couponItemCode);
		if (couponItem != null) {
			if (StringUtils.isBlank(couponItem.getMemberId())) {
				addActionMessage("礼卷尚未被取得");
				return queryCouponByCouponItemCode();
			}
			if (StringUtils.isNotBlank(couponItem.getOrderId())) {
				addActionMessage("礼卷已被使用");
				return queryCouponByCouponItemCode();
			}
			this.couponUuid = couponItem.getCoupon().getUuid();
			setCoupon(couponItem.getCoupon());
			setCouponItem(couponItem);
			startDate = DateUtil.convertDateToString(EcConstant.PATTERN_TIMESTAMP_HH_MM, couponItem.getStartDate());
			endDate = DateUtil.convertDateToString(EcConstant.PATTERN_TIMESTAMP_HH_MM, couponItem.getEndDate());
			setStartTime(startDate.substring(11, 16));
			setEndTime(endDate.substring(11, 16));
			setStartDate(startDate.substring(0, 10));
			setEndDate(endDate.substring(0, 10));
			return RESULT_EDIT_COUPON_ITEM;
		}
		addActionMessage("优惠码（Coupon Item Code）查无资料");
		return RESULT_QUERY_COUPON_BY_COUPON_ITEM_CODE;
	}

	/**
	 * 更新couponItem
	 * 
	 * @return
	 * @throws Exception
	 */
	public String updateCouponItem() throws Exception {
		CouponItem couponItem = couponService.getCouponItemByCode(getCouponItemCode());
		if (couponItem == null) {
			addActionMessage("优惠码（Coupon Item Code）查无资料");
			return RESULT_EDIT_COUPON_ITEM;
		}
		if (StringUtils.isBlank(couponItem.getMemberId())) {
			addActionMessage("礼卷尚未被取得");
			return queryCouponByCouponItemCode();
		}
		if (StringUtils.isNotBlank(couponItem.getOrderId())) {
			addActionMessage("优惠券已被使用");
			return queryCouponByCouponItemCode();
		}
		couponItem.setStartDate(DateUtil.convertStringToDate(EcConstant.PATTERN_TIMESTAMP_HH_MM, startDate + " "
				+ startTime));
		couponItem.setEndDate(DateUtil.convertStringToDate(EcConstant.PATTERN_TIMESTAMP_HH_MM, endDate + " " + endTime));
		couponService.updateCouponItem(couponItem, couponItem.getMemberId());
		if (FROM_COUPON.equals(from)) { // 返回coupon檢視頁
			setCouponUuid(couponItem.getCoupon().getUuid());
			return view();
		}
		// 返回CoonItem 檢視頁
		return queryCouponByCouponItemCode();
	}

	/**
	 * 取消已註冊coupon
	 * 
	 * @return
	 * @throws Exception
	 */
	public String jsonCancelCoupon() throws Exception {
		CouponItem couponItem = couponService.getCouponItemByCode(getCouponItemCode());
		if (couponItem == null) {
			jsonResult = "unfind";
			return "jsonCancelCoupon";
		}
		if (StringUtils.isBlank(couponItem.getMemberId())) {
			jsonResult = "not_reg";
			return "jsonCancelCoupon";
		}
		if (StringUtils.isNotBlank(couponItem.getOrderId())) {
			jsonResult = "is_used";
			return "jsonCancelCoupon";
		}
		String memberId = couponItem.getMemberId();
		couponItem.setRegDate(null);
		couponItem.setMemberId(null);
		couponService.updateCouponItem(couponItem, memberId);
		jsonResult = "OK";
		return "jsonCancelCoupon";
	}

	// 編輯時 applyRangeTypeExtension 的欄位初始值
	public String getApplyRangeTypeExtensionEditDisplayInitial() {
		if (this.couponUuid == null) {
			return "";
		}
		this.coupon = this.couponService.get(this.couponUuid);
		if (this.coupon == null) {
			return "";
		}
		if (this.coupon.getApplyRangeTypeExtensionArray() == null) {
			return "";
		}

		List<String> itemIdList = new ArrayList<String>();
		for (String applyRangeTypeExtension : this.coupon.getApplyRangeTypeExtensionArray()) {
			String[] splittedApplyRangeTypeExtension = StringUtils.split(applyRangeTypeExtension, CATEGORY_PATH_SEPARATOR);
			if (splittedApplyRangeTypeExtension == null) {
				continue;
			}
			String itemId = splittedApplyRangeTypeExtension[splittedApplyRangeTypeExtension.length - 1];
			itemIdList.add(itemId);
		}

		return StringUtils.join(itemIdList.toArray(), APPLY_RANGE_TYPE_EXTENSION_SEPARATOR);
	}

	// 檢視時 applyRangeTypeExtension 的顯示值
	public String getApplyRangeTypeExtensionDisplay() {
		if (this.coupon == null) {
			return "";
		}

		String[] applyRangeTypeExtensionArray = this.coupon.getApplyRangeTypeExtensionArray();
		if (applyRangeTypeExtensionArray == null) {
			return "";
		}

		if (getCoupon().getApplyRangeType().equals(Coupon.ApplyRangType.CATEGORY)) {
			return applyRangeTypeExtensionDisplayForCategory(applyRangeTypeExtensionArray);
		} else if (getCoupon().getApplyRangeType().equals(Coupon.ApplyRangType.PRODUCT)) {
			return applyRangeTypeExtensionDisplayForProduct(applyRangeTypeExtensionArray);
		}

		return "";
	}

	public String getSendMail() {
		return sendMail;
	}

	public void setSendMail(String sendMail) {
		this.sendMail = sendMail;
	}

	public String getCouponItemCode() {
		return this.couponItemCode;
	}

	public void setCouponItemCode(String couponItemCode) {
		this.couponItemCode = couponItemCode;
	}

	public Coupon getCoupon() {
		return this.coupon;
	}

	public CouponItem getCouponItem() {
		return this.couponItem;
	}

	public void setCoupon(Coupon coupon) {
		this.coupon = coupon;
	}

	public void setCouponItem(CouponItem couponItem) {
		this.couponItem = couponItem;
	}

	public BigDecimal getMinimumProductPrice() {
		return this.minimumProductPrice;
	}

	public void setMinimumProductPrice(BigDecimal minimumProductPrice) {
		this.minimumProductPrice = minimumProductPrice;
	}

	public CategoryService getCategoryService() {
		return this.categoryService;
	}

	public void setCategoryService(CategoryService categoryService) {
		this.categoryService = categoryService;
	}

	public ProductService getProductService() {
		return this.productService;
	}

	public void setProductService(ProductService productService) {
		this.productService = productService;
	}

	public boolean isCreatingCoupon() {
		return this.creatingCoupon;
	}

	public void setCreatingCoupon(boolean creatingCoupon) {
		this.creatingCoupon = creatingCoupon;
	}

	public Boolean getIsOnce() {
		return this.isOnce;
	}

	public void setIsOnce(Boolean isOnce) {
		this.isOnce = isOnce;
	}

	public String getStartTime() {
		return this.startTime;
	}

	public void setStartTime(String startTime) {
		this.startTime = startTime;
	}

	public String getEndTime() {
		return this.endTime;
	}

	public void setEndTime(String endTime) {
		this.endTime = endTime;
	}

	public String getActivityLink() {
		return this.activityLink;
	}

	public void setActivityLink(String activityLink) {
		this.activityLink = activityLink;
	}

	private String applyRangeTypeExtensionDisplayForCategory(String[] applyRangeTypeExtensionArray) {
		if (applyRangeTypeExtensionArray == null) {
			return "";
		}

		StringBuffer resultBuffer = new StringBuffer();

		for (int i = 0; i < applyRangeTypeExtensionArray.length; i++) {
			String oneCategoryPath = applyRangeTypeExtensionArray[i];
			String[] categoryPathArray = StringUtils.split(oneCategoryPath, CATEGORY_PATH_SEPARATOR);

			if (categoryPathArray == null) {
				continue;
			}
			if (categoryPathArray.length <= 0) {
				continue;
			}
			String categoryIdString = StringUtils.trimToNull(categoryPathArray[categoryPathArray.length - 1]);
			Long categoryId = null;
			if (categoryIdString != null) {
				categoryId = Long.valueOf(categoryIdString);
			}
			Category category = this.categoryService.get(categoryId);

			// 格式參考行銷活動管理：category name (category id)(category path)
			String categoryNameDisplay;
			String categoryIdDisplay;
			String categoryPathDisplay;
			if (category == null) {
				categoryNameDisplay = "???";
				categoryIdDisplay = categoryIdString;
				categoryPathDisplay = oneCategoryPath;
			} else {
				categoryNameDisplay = category.getName();
				categoryIdDisplay = category.getId().toString();
				categoryPathDisplay = category.getCategoryPath();
			}
			if (i > 0) {
				resultBuffer.append("<br/>");
			}
			resultBuffer.append(categoryNameDisplay);
			resultBuffer.append(" ");
			resultBuffer.append("(");
			resultBuffer.append(categoryIdDisplay);
			resultBuffer.append(")");
			resultBuffer.append(" ");
			resultBuffer.append("(");
			resultBuffer.append(categoryPathDisplay);
			resultBuffer.append(")");
		}

		return resultBuffer.toString();
	}

	private String applyRangeTypeExtensionDisplayForProduct(String[] applyRangeTypeExtensionArray) {
		if (applyRangeTypeExtensionArray == null) {
			return "";
		}

		StringBuffer resultBuffer = new StringBuffer();

		for (int i = 0; i < applyRangeTypeExtensionArray.length; i++) {
			String oneProductId = StringUtils.trimToNull(applyRangeTypeExtensionArray[i]);

			if (oneProductId == null) {
				continue;
			}

			Product product = this.productService.get(oneProductId);

			// 格式參考行銷活動管理：category name (category id)(category path)
			String productNameDisplay;
			String productIdDisplay;
			if (product == null) {
				productNameDisplay = "?";
				productIdDisplay = oneProductId;
			} else {
				productNameDisplay = product.getProductName();
				productIdDisplay = product.getProductId();
			}
			if (i > 0) {
				resultBuffer.append("<br/>");
			}
			resultBuffer.append(productNameDisplay);
			resultBuffer.append(" ");
			resultBuffer.append("(");
			resultBuffer.append(productIdDisplay);
			resultBuffer.append(")");
			resultBuffer.append(" ");
		}
		return resultBuffer.toString();
	}

	private void setStartEndDate(Coupon coupon) throws ParseException {
		sd = null;
		ed = null;
		if (StringUtils.isNotBlank(this.startDate)) {
			String startTimePattern = "yyyy-MM-dd HH:mm";
			String startTimePointString = this.startDate + " " + this.startTime;
			sd = DateUtils.parseDate(startTimePointString, new String[] { startTimePattern });
		}
		if (StringUtils.isNotBlank(this.endDate)) {
			String endTimePattern = "yyyy-MM-dd HH:mm:ss";
			String endTimePointString = this.endDate + " " + this.endTime + ":59";
			ed = DateUtils.parseDate(endTimePointString, new String[] { endTimePattern });
		}

	}

	public Menu getMenuBudget() {
		return menuBudget;
	}

	public void setMenuBudget(Menu menuBudget) {
		this.menuBudget = menuBudget;
	}

	public String getBudget() {
		return budget;
	}

	public void setBudget(String budget) {
		this.budget = budget;
	}

	public List<CouponItem> getCouponItems() {
		return couponItems;
	}

	public void setCouponItems(List<CouponItem> couponItems) {
		this.couponItems = couponItems;
	}

	public String getFrom() {
		return from;
	}

	public void setFrom(String from) {
		this.from = from;
	}

	public String getJsonResult() {
		return jsonResult;
	}

	public void setJsonResult(String jsonResult) {
		this.jsonResult = jsonResult;
	}

}
